package com.yourenbang.lingyun.transaction.web.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.pay.PayFromEnum;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeEnum;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeStatusEnum;
import com.yourenbang.lingyun.core.exception.UserBizException;
import com.yourenbang.lingyun.core.util.redis.CacheKey;
import com.yourenbang.lingyun.core.util.redis.CacheKey.CacheKeyPrefix2;
import com.yourenbang.lingyun.core.util.redis.RedisUtils;
import com.yourenbang.lingyun.domain.PayChannelParam;
import com.yourenbang.lingyun.domain.PayChannelParamExample;
import com.yourenbang.lingyun.domain.PayType;
import com.yourenbang.lingyun.domain.PayTypeExample;
import com.yourenbang.lingyun.mapper.PayChannelParamMapper;
import com.yourenbang.lingyun.mapper.PayTypeMapper;
import com.yourenbang.transaction.api.service.pay.PayTypeApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RestController
public class PayTypeApiServiceImpl implements PayTypeApiService {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PayTypeMapper payTypeMapper;
    @Autowired
    private PayChannelParamMapper payChannelParamMapper;


    /**
     * 获取支付通道参数
     * @param payChannelId
     */
    @Override
    public Map<String, String> getPayParamsByChannel(Integer payChannelId) {
        CacheKey redisKey = getPayParamsKey(payChannelId);
        Map<String, String> redisMap = redisUtils.get(redisKey, Map.class);
        if(MapUtils.isEmpty(redisMap)){
            PayChannelParamExample paramExample = new PayChannelParamExample();
            paramExample.createCriteria().andPayChannelIdEqualTo(payChannelId);
            List<PayChannelParam> params = payChannelParamMapper.selectByExample(paramExample);
            redisMap = new HashMap<>();
            for(PayChannelParam paramPO : params){
                redisMap.put(paramPO.getCode(), paramPO.getValue());
            }
            redisUtils.set(redisKey, redisMap, 60);
        }
        return redisMap;
    }

    /**
     * 获取支付通道参数
     * @param payType
     * @param payFrom
     */
    @Override
    public Map<String, String> getPayParams(PayTypeEnum payType, PayFromEnum payFrom) {
        CacheKey redisKey = getPayParamsKey(payType, payFrom);
        Map<String, String> redisMap = redisUtils.get(redisKey, Map.class);
        if (false && MapUtils.isNotEmpty(redisMap)) {
            return redisMap;
        }
        PayType payTypeRecord = getPayTypeRcord(payType, payFrom);
        PayChannelParamExample paramExample = new PayChannelParamExample();
        paramExample.createCriteria().andPayChannelIdEqualTo(payTypeRecord.getPayChannel());
        List<PayChannelParam> params = payChannelParamMapper.selectByExample(paramExample);
        redisMap = new HashMap<>();
        for (PayChannelParam paramPO : params) {
            redisMap.put(paramPO.getCode(), paramPO.getValue());
        }
        //可用状态
        redisMap.put("payTypeStatus", "" + (Objects.isNull(payTypeRecord.getStatus()) ? PayTypeStatusEnum.enable : payTypeRecord.getStatus()));
        redisUtils.set(redisKey, redisMap, 60);
        return redisMap;
    }

    private PayType getPayTypeRcord(PayTypeEnum payType, PayFromEnum payFrom) {
        PayTypeExample payTypeExample = new PayTypeExample();
        payTypeExample.createCriteria().andCodeEqualTo(payType.getCode()).andPayFromEqualTo(payFrom.getCode());
        List<PayType> payTypes = payTypeMapper.selectByExample(payTypeExample);
        if(CollectionUtils.isEmpty(payTypes)){
            throw new UserBizException(BizCodeMessages.UNKNOWN_ERROR, "未找到支付方式");
        }
        PayType payTypePo = payTypes.get(0);
        if(Objects.isNull(payTypePo.getPayChannel())){
            throw new UserBizException(BizCodeMessages.UNKNOWN_ERROR, "未找到支付通道");
        }
        return payTypePo;
    }

    private CacheKey getPayParamsKey(Integer payChannelId){
        CacheKey key = new CacheKey(CacheKeyPrefix2.pay,
                StringUtils.join(new String[]{"PayChannelParam",payChannelId+""}, ":"));
        log.debug("获取支付通道参数,key:{}", JSON.toJSONString(key));
        return key;
    }

    private CacheKey getPayParamsKey(PayTypeEnum payType, PayFromEnum payFrom){
        CacheKey key = new CacheKey(CacheKeyPrefix2.pay,
                StringUtils.join(new String[]{"PayChannelParam",payType.getCode(), payFrom.getCode()}, ":"));
        log.debug("获取支付通道参数,key:{}", JSON.toJSONString(key));
        return key;
    }

}
